package com.skyinno.mrms.common.service.impl;

import java.io.File;
import java.security.MessageDigest;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.WebUtils;

import com.skyinno.mrms.common.dao.BaseDao;
import com.skyinno.mrms.common.model.FileModel;
import com.skyinno.mrms.common.model.PageModel;
import com.skyinno.mrms.common.model.UploadFile;
import com.skyinno.mrms.common.service.BaseService;
import com.skyinno.mrms.redis.RedisUtil;
import com.skyinno.mrms.utils.Config;
import com.skyinno.mrms.utils.Constants;
import com.skyinno.mrms.utils.Message;

public class BaseServiceImpl implements BaseService, ApplicationContextAware {
    protected Logger logger = Logger.getLogger(this.getClass());

    protected ApplicationContext ac;

    public DecimalFormat intDf = new DecimalFormat("#");

    @Autowired
    private BaseDao dao;	

    @Autowired 
    protected Message message;

    RedisUtil redis = RedisUtil.getInstance();

    public static final String ROWS = "rows";

    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        this.ac = arg0;
    }

    @Override
    public void resetStart(PageModel model) {
        if ((model.getPage() - 1) * model.getRows() + 1 > model.getCount()) {
            int page = model.getCount() / model.getRows();
            model.setPage(page == 0 ? 1 : page);
        }
    }

    @Override
    public Map<String, Object> setGridData(int total, Collection<?> rows) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("total", total);
        data.put(ROWS, rows);
        return data;
    }

    @Override
    public void setOrder(DetachedCriteria criteria, PageModel model) {
        String sort = StringUtils.isBlank(model.getSort()) ? "id" : model
                .getSort();
        if ("asc".equalsIgnoreCase(model.getOrder())) {
            criteria.addOrder(Order.asc(sort));
        } else {
            criteria.addOrder(Order.desc(sort));
        }
    }

    @Override
    public String crypt(String str) throws Exception {
        StringBuilder hexString = new StringBuilder();
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str.getBytes(Constants.ENCODE));
        byte[] hash = md.digest();
        for (int i = 0; i < hash.length; i++) {
            if ((0xff & hash[i]) < 0x10) {
                hexString.append("0" + Integer.toHexString((0xFF & hash[i])));
            } else {
                hexString.append(Integer.toHexString(0xFF & hash[i]));
            }
        }
        return hexString.toString();
    }

    protected String uuid() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    @Override
    public String saveFile(MultipartFile file, String dir, String type)
            throws Exception {
        Timestamp ts = new Timestamp(System.currentTimeMillis());
        String image = dir + new SimpleDateFormat("yyyy-MM-dd").format(ts)
                + "/img_" + this.uuid();
        FileUtils.writeByteArrayToFile(new File(Config
                .getProperty("file.rootDir")
                + image), file.getBytes());
        UploadFile model = new UploadFile();
        model.setPath(image);
        model.setName(file.getOriginalFilename());
        model.setType(type);
        model.setCreateTime(ts);
        model.setFlag(Constants.VALID);
        return (String) dao.save(model);
    }
	
	public String getUUID(){
		return UUID.randomUUID().toString().replaceAll("-", "");
	}
	
    @SuppressWarnings("unchecked")
    @Override
    public FileModel fileEx(String id) {
        FileModel fm = new FileModel();
        List<Object[]> objectList = dao.queryAll(DetachedCriteria.forClass(
                UploadFile.class).add(Restrictions.idEq(id)).setProjection(
                Projections.projectionList().add(Property.forName("path")).add(
                        Property.forName("fileName")).add(
                        Property.forName("name"))));
        if (CollectionUtils.isNotEmpty(objectList)) {
            Object[] object = objectList.get(0);
            fm.setSource(Config.getProperty("file.rootDir") + object[0]
                    + (object[1] == null ? "" : object[1]));
            fm.setFileName((String) object[2]);
        }
        return fm;
    }
	
	/**
	 * 获取客户端ip地址
	 * @param request
	 * @return
	 */
    @Override
	public String getIpAddr(HttpServletRequest request) {  
	    String ip = request.getHeader("x-forwarded-for");  
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
	        ip = request.getHeader("Proxy-Client-IP");  
	    }  
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
	        ip = request.getHeader("WL-Proxy-Client-IP");  
	    }  
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
	        ip = request.getRemoteAddr();  
	    }  
	    return ip;  
	}
	/**
	 * 获取登录用户ID
	 * @param request
	 * @return
	 */
	@Override
	public String getLoginUser(HttpServletRequest request) {
        return (String) WebUtils.getSessionAttribute(request,
                Constants.LOGIN_USER);
    }
}
